package com.kelvem.saas.workbanch.core.manager.service;

import com.alibaba.fastjson.JSON;
import com.kelvem.saas.workbanch.core.base.BaseCriteria;
import com.kelvem.saas.workbanch.core.base.BaseService;
import com.kelvem.saas.workbanch.core.base.Page;
import com.kelvem.saas.workbanch.core.exception.SaasAssert;
import com.kelvem.saas.workbanch.core.exception.SaasException;
import com.kelvem.saas.workbanch.core.manager.dao.MetaTableColumnDao;
import com.kelvem.saas.workbanch.core.manager.model.MetaTableColumnEntity;
import com.kelvem.saas.workbanch.core.manager.model.MetaTableEntity;
import com.kelvem.saas.workbanch.core.manager.request.MetaTableColumnQueryVo;
import com.kelvem.saas.workbanch.core.model.SchemaColumnModel;
import com.kelvem.saas.workbanch.core.utils.DateUtil;
import com.kelvem.saas.workbanch.fsm.dao.BaseDao;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 实体表字段Service
 *
 * @author kelvem
 * @version 1.0
 */
@Service
@Slf4j
public class MetaTableColumnService extends BaseService<MetaTableColumnEntity, MetaTableColumnQueryVo> {

    @Resource
    private MetaTableColumnDao metaTableColumnDao;

    @Resource
    private GraphqlService graphqlService;

    /**
     * 增加实体表字段
     *
     * @param metaTableColumn 实体表字段信息
     * @return Long 主键
     */
    @Transactional(rollbackFor = Exception.class)
    public Long addMetaTableColumn(MetaTableColumnEntity metaTableColumn) {
        
        log.info("MetaTableColumnService:addMetaTableColumn:start, metaTableColumn=【{}】", metaTableColumn);
        SaasAssert.notNull(metaTableColumn);
        
        try {
            if (metaTableColumn.getCreateTime() == null) {
                metaTableColumn.setCreateTime(DateUtil.now());
            }
            if (metaTableColumn.getUpdateTime() == null) {
                metaTableColumn.setUpdateTime(DateUtil.now());
            }
        
            metaTableColumnDao.insert(metaTableColumn);
            Long metaTableColumnId = metaTableColumn.getId();
            log.info("MetaTableColumnService:addMetaTableColumn:end, metaTableColumnId={}", metaTableColumnId);
        
            return metaTableColumn.getId();
        } catch (Exception e) {
            String msg = String.format("MetaTableColumnService:addMetaTableColumn:error, %s", e.getMessage());
            log.error(msg, e);
            throw new SaasException(msg);
        }
    }

    /**
     * 修改实体表字段
     *
     * @param metaTableColumn 实体表字段信息
     * @return 更新记录数
     */
    @Transactional(rollbackFor = Exception.class)
    public int updateMetaTableColumn(MetaTableColumnEntity metaTableColumn) {
        
        log.info("MetaTableColumnService:updateMetaTableColumn:start, metaTableColumn=【{}】", metaTableColumn);
        SaasAssert.notNull(metaTableColumn);
        SaasAssert.notNull(metaTableColumn.getId());

        try {
            int count = metaTableColumnDao.updateById(metaTableColumn);
            log.info("MetaTableColumnService:updateMetaTableColumn:end, count={}", count);
            return count;
        } catch (Exception e) {
            String msg = String.format("MetaTableColumnService:updateMetaTableColumn:error, %s", e.getMessage());
            log.error(msg, e);
            throw new SaasException(msg);
        }
    }

    /**
     * 删除实体表字段
     *
     * @param metaTableColumnId 实体表字段id
     * @return 删除记录数
     */
    @Transactional(rollbackFor = Exception.class)
    public int deleteMetaTableColumn(Long metaTableColumnId) {

        log.info("MetaTableColumnService:deleteMetaTableColumn:start, metaTableColumnId={}", metaTableColumnId);
        SaasAssert.notNull(metaTableColumnId);
        
        try {
            int count = metaTableColumnDao.deleteById(metaTableColumnId);
            log.info("MetaTableColumnService:deleteMetaTableColumn:end, count={}", count);
            return count;
        } catch (Exception e) {
            String msg = String.format("MetaTableColumnService:deleteMetaTableColumn:error, %s", e.getMessage());
            log.error(msg, e);
            throw new SaasException(msg);
        }
    }
    
    /**
     * 查询实体表字段分页数据
     *
     * @param metaTableColumnQueryVo 查询用
     * @return Page<MetaTableColumnDto>
     */
    public Page<MetaTableColumnEntity> queryMetaTableColumnPage(MetaTableColumnQueryVo metaTableColumnQueryVo) {
        
        log.info("MetaTableColumnService:queryMetaTableColumnPage:start, metaTableColumnQueryVo=【{}】", metaTableColumnQueryVo);
        SaasAssert.notNull(metaTableColumnQueryVo);
        
        try {
            Page<MetaTableColumnEntity> page = super.queryPage(metaTableColumnQueryVo);
            
            List<MetaTableColumnEntity> columnList = page.getRecords();
            for (int i = 1; i < columnList.size(); i++) {
                MetaTableColumnEntity metaTableColumn = columnList.get(i);
                if ("id".equalsIgnoreCase(metaTableColumn.getEnName())) {
                    columnList.remove(i);
                    columnList.add(0, metaTableColumn);
                    break;
                }
            }
            
            log.info("MetaTableColumnService:queryMetaTableColumnPage:end, page.size={}", page.getRecords().size());
            return page;
        } catch (Exception e) {
            String msg = String.format("MetaTableColumnService:queryMetaTableColumnPage:error, %s", e.getMessage());
            log.error(msg, e);
            throw new SaasException(msg);
        }
    }

    /**
     * 查询实体表字段列表数据
     *
     * @param metaTableId 实体表id
     * @return List<MetaTableColumn>
     */
    public List<MetaTableColumnEntity> queryMetaTableColumnList(Long metaTableId) {

        log.info("MetaTableColumnService:queryMetaTableColumnList:start, metaTableId=【{}】", metaTableId);
        SaasAssert.notNull(metaTableId);

        try {
            MetaTableColumnQueryVo metaTableColumnQueryVo = new MetaTableColumnQueryVo();
            metaTableColumnQueryVo.setMetaTableId(metaTableId);

            List<MetaTableColumnEntity> list = super.queryList(metaTableColumnQueryVo);
            log.info("MetaTableColumnService:queryMetaTableColumnList:end, list.size={}", list.size());
            return list;
        } catch (Exception e) {
            String msg = String.format("MetaTableColumnService:queryMetaTableColumnList:error, %s", e.getMessage());
            log.error(msg, e);
            throw new SaasException(msg);
        }
    }
    
    /**
     * 查询实体表字段列表数据
     *
     * @param metaTableColumnQueryVo 查询用
     * @return List<MetaTableColumn>
     */
    public List<MetaTableColumnEntity> queryMetaTableColumnList(MetaTableColumnQueryVo metaTableColumnQueryVo) {
        
        log.info("MetaTableColumnService:queryMetaTableColumnList:start, metaTableColumnQueryVo=【{}】", metaTableColumnQueryVo);
        SaasAssert.notNull(metaTableColumnQueryVo);
        
        try {
            List<MetaTableColumnEntity> list = super.queryList(metaTableColumnQueryVo);
            log.info("MetaTableColumnService:queryMetaTableColumnList:end, list.size={}", list.size());
            return list;
        } catch (Exception e) {
            String msg = String.format("MetaTableColumnService:queryMetaTableColumnList:error, %s", e.getMessage());
            log.error(msg, e);
            throw new SaasException(msg);
        }
    }

    /**
     * 根据id查询实体表字段信息
     *
     * @param metaTableColumnId 实体表字段id
     * @return MetaTableColumn
     */
    public MetaTableColumnEntity getMetaTableColumnById(Long metaTableColumnId) {

        log.info("MetaTableColumnService:getMetaTableColumnById:start, metaTableColumnId={}", metaTableColumnId);
        SaasAssert.notNull(metaTableColumnId);
        
        try {
            MetaTableColumnEntity metaTableColumn = metaTableColumnDao.selectById(metaTableColumnId);
            log.info("MetaTableColumnService:getMetaTableColumnById:end, metaTableColumnInfo=【{}】", metaTableColumn);
            return metaTableColumn;
        } catch (Exception e) {
            String msg = String.format("MetaTableColumnService:getMetaTableColumnById:error, %s", e.getMessage());
            log.error(msg, e);
            throw new SaasException(msg);
        }
    }

    /**
     * 构建查询用Criteria
     * 基类的queryPage, queryList方法使用
     *
     * @param queryVo 查询用
     * @return BaseCriteria
     */
    @Override
    public BaseCriteria<MetaTableColumnEntity> buildQueryCriteria(MetaTableColumnQueryVo queryVo) {
        BaseCriteria<MetaTableColumnEntity> criteria = new BaseCriteria<>();
        criteria.orderByDesc("meta_table_id");
        criteria.orderByAsc("sort_no");

        // 主键
        Long id = queryVo.getId();
        if (super.isNotEmpty(id)) {
            criteria.andEqualTo("id", queryVo.getId());
        }

        // 创建时间
        Date startCreateTime = queryVo.getStartCreateTime();
        if(super.isNotEmpty(startCreateTime)) {
            criteria.andGreaterThanOrEqualTo("createTime", startCreateTime);
        }
        Date endCreateTime = queryVo.getEndCreateTime();
        if(super.isNotEmpty(endCreateTime)) {
            criteria.andLessThanOrEqualTo("createTime", endCreateTime);
        }

        // 实体表id
        Long metaTableId = queryVo.getMetaTableId();
        if (super.isNotEmpty(metaTableId)) {
            criteria.andEqualTo("metaTableId", metaTableId);
        }

        // 控件类型, number:数字; varchar128:短文字; varchar1024:长文字; biz_id:主键; biz_state:状态
        String controlType = queryVo.getControlType();
        if (super.isNotEmpty(controlType)) {
            criteria.andEqualTo("controlType", controlType);
        }

        // 字段类型, int:数字; varchar:文字; datetime:时间; bigint:长数字
        String dbType = queryVo.getDbType();
        if (super.isNotEmpty(dbType)) {
            criteria.andEqualTo("dbType", dbType);
        }

        // 字段默认值
        String defaultValue = queryVo.getDefaultValue();
        if (super.isNotEmpty(defaultValue)) {
            criteria.andEqualTo("defaultValue", defaultValue);
        }

        // 必填, 1:必填; 0:选填
        Integer requireFlag = queryVo.getRequireFlag();
        if (super.isNotEmpty(requireFlag)) {
            criteria.andEqualTo("requireFlag", requireFlag);
        }

        // 可排序, 1:可排序; false:不可排序
        Integer sortFlag = queryVo.getSortFlag();
        if (super.isNotEmpty(sortFlag)) {
            criteria.andEqualTo("sortFlag", sortFlag);
        }

        // 列展示, 1:展示; 0:不展示
        Integer showFlag = queryVo.getShowFlag();
        if (super.isNotEmpty(showFlag)) {
            criteria.andEqualTo("showFlag", showFlag);
        }

        // 可查询, 1:可查询; 0:不可查询
        Integer queryAble = queryVo.getQueryAble();
        if (super.isNotEmpty(queryAble)) {
            criteria.andEqualTo("queryAble", queryAble);
        }

        // 可新增, 1:可新增; 0:不可新增
        Integer addAble = queryVo.getAddAble();
        if (super.isNotEmpty(addAble)) {
            criteria.andEqualTo("addAble", addAble);
        }

        // 可编辑, 1:编辑; 0:不可编辑
        Integer editAble = queryVo.getEditAble();
        if (super.isNotEmpty(editAble)) {
            criteria.andEqualTo("editAble", editAble);
        }

        // 字段来源, manual:人工; extends:继承
        String sourceType = queryVo.getSourceType();
        if (super.isNotEmpty(sourceType)) {
            criteria.andEqualTo("sourceType", sourceType);
        }

        // 创建人
        String createUid = queryVo.getCreateUid();
        if (super.isNotEmpty(createUid)) {
            criteria.andEqualTo("createUid", createUid);
        }

        // 更新人
        String updateUid = queryVo.getUpdateUid();
        if (super.isNotEmpty(updateUid)) {
            criteria.andEqualTo("updateUid", updateUid);
        }

        return criteria;
    }

    @Override
    public BaseDao<MetaTableColumnEntity> getDao() {
        return this.metaTableColumnDao;
    }
    
    
    /**
     * 删除实体表字段
     *
     * @param metaTableId 实体表id
     * @return 删除记录数
     */
    @Transactional(rollbackFor = Exception.class)
    public int deleteByParentMetaTableId(Long metaTableId) {
        
        log.info("MetaTableColumnService:deleteByParentMetaTableId:start, metaTableId={}", metaTableId);
        SaasAssert.notNull(metaTableId);
        
        try {
            int count = metaTableColumnDao.deleteByParentMetaTableId(metaTableId);
            log.info("MetaTableColumnService:deleteByParentMetaTableId:end, count={}", count);
            return count;
        } catch (Exception e) {
            String msg = String.format("MetaTableColumnService:deleteByParentMetaTableId:error, %s", e.getMessage());
            log.error(msg, e);
            throw new SaasException(msg);
        }
    }
    
    /**
     * 批量保存实体表字段
     *
     * @param metaTableColumnList 实体表id
     * @return 删除记录数
     */
    @Transactional(rollbackFor = Exception.class)
    public Integer batchMetaTableColumn(List<MetaTableColumnEntity> metaTableColumnList) {
        
        log.info("MetaTableColumnService:batchMetaTableColumn:start, metaTableColumnList={}", metaTableColumnList);
        SaasAssert.notNull(metaTableColumnList);
        
        try {
            if (metaTableColumnList.isEmpty()) {
                return 0;
            }
    
            Long metaTableId = metaTableColumnList.get(0).getMetaTableId();
            log.debug("batch, metaTableId={}", metaTableId);
            List<MetaTableColumnEntity> originalMetaTableColumnList = this.queryMetaTableColumnList(metaTableId);
    
            // 更新sortNo
            for (int i = 0; i < metaTableColumnList.size(); i++) {
                MetaTableColumnEntity metaTableColumn = metaTableColumnList.get(i);
                metaTableColumn.setSortNo(i);
            }
            
            int count = 0;
            /**
             * 更新
             */
            for (MetaTableColumnEntity metaTableColumn :
                    metaTableColumnList) {
                if (metaTableColumn.getId() != null) {
                    this.updateMetaTableColumn(metaTableColumn);
                    count++;
                }
            }
    
            /**
             * 插入
             */
            for (MetaTableColumnEntity metaTableColumn :
                    metaTableColumnList) {
                if (metaTableColumn.getId() == null) {
                    metaTableColumn.setMetaTableId(metaTableId);
                    this.addMetaTableColumn(metaTableColumn);
                    count++;
                }
            }
    
            /**
             * 删除
             */
            Map<Long, MetaTableColumnEntity> columnMap = new HashMap<>();
            for (MetaTableColumnEntity metaTableColumn :
                    metaTableColumnList) {
                if (metaTableColumn.getId() != null) {
                    columnMap.put(metaTableColumn.getId(), metaTableColumn);
                }
            }
            
            for (MetaTableColumnEntity originalEnityTableColumn :
                    originalMetaTableColumnList) {
                if (!columnMap.containsKey(originalEnityTableColumn.getId())) {
                    this.deleteMetaTableColumn(originalEnityTableColumn.getId());
                    count++;
                }
            }
    
            return count;
        } catch (Exception e) {
            String msg = String.format("MetaTableColumnService:batchMetaTableColumn:error, %s", e.getMessage());
            log.error(msg, e);
            throw new SaasException(msg);
        }
    }

    /**
     * number:数字; varchar128:短文字; varchar1024:长文字; biz_id:主键; biz_state:状态;',
     *
     * @param metaTableColumn 对象
     * @return 字段长度
     */
    public int calColSize(MetaTableColumnEntity metaTableColumn) {
        String controlType = metaTableColumn.getControlType();
        String dbType = metaTableColumn.getDbType();
        if ("biz_id".equalsIgnoreCase(controlType)) {
            return 20;
        } else if ("biz_state".equalsIgnoreCase(controlType)) {
            return 64;
        } else if ("number".equalsIgnoreCase(controlType)) {
            return 11;
        } else if ("varchar64".equalsIgnoreCase(controlType)) {
            return 64;
        } else if ("varchar128".equalsIgnoreCase(controlType)) {
            return 128;
        } else if ("varchar1024".equalsIgnoreCase(controlType)) {
            return 1024;
        } else if ("password".equalsIgnoreCase(controlType)) {
            return 32;
        } else if ("datetime".equalsIgnoreCase(controlType)) {
            return 0;
        } else if ("varchar".equalsIgnoreCase(dbType)) {
            return 32;
        } else {
            return 0;
        }
    }

    @Transactional(rollbackFor = Exception.class)
    public void copyMetaTableColumn(List<MetaTableColumnEntity> metaTableColumnList, Long metaTableId) {

        for (MetaTableColumnEntity metaTableColumn:
                metaTableColumnList) {
            metaTableColumn.setId(null);
            metaTableColumn.setCreateTime(DateUtil.now());
            metaTableColumn.setUpdateTime(DateUtil.now());
            metaTableColumn.setMetaTableId(metaTableId);
            if ("id".equalsIgnoreCase(metaTableColumn.getSourceType())) {
                metaTableColumn.setSourceType("id");
            } else {
                metaTableColumn.setSourceType("extends");
            }
            this.addMetaTableColumn(metaTableColumn);
        }
    }

    @Transactional(rollbackFor = Exception.class)
    public Integer importTableColumn(MetaTableEntity metaTable, Long importTableId) {

        /**
         * 值验证
         * id       bigint  主键(PRI)
         * state    varchar (>32)
         * enable   tinyint 是否启用(有效)
         * del_flag tinyint 逻辑删除
         *
         * *_type   varchar (>32) 例如: 类型名称, pending:待处理; commit: 已提交; pass: 审核通过; fail:审核失败; end: 完结
         * *_no     varchar 对象编码, 展示为主(唯一)
         * *_flag   tinyint 0:否, 1:是
         * *_url    varchar (>2048) 某url
         * *_time   YYYY-MM-DD hh:mm:ss
         * *_date   YYYY-MM-DD
         * *_price  价格多币种
         * *_amount 价格主币种
         */
        String sql ="" +
                " select c.COLUMN_NAME columnName, c.ORDINAL_POSITION ordinalPosition, c.COLUMN_DEFAULT columnDefault, \n" +
                " case when c.IS_NULLABLE = 'NO' then 0 else 1 end nullableFlag, \n" +
                " c.DATA_TYPE dataType, c.CHARACTER_MAXIMUM_LENGTH characterLength, c.NUMERIC_PRECISION numericPrecision, c.NUMERIC_SCALE numericScale,  \n" +
                " c.COLUMN_TYPE columnType, c.COLUMN_KEY columnKey, c.COLUMN_COMMENT columnComment\n" +
                " from `information_schema`.COLUMNS c \n" +
                " where c.table_schema = 'saas_bench' and c.table_name='" + metaTable.getTableEnName() + "'\n" +
                " order by c.ORDINAL_POSITION";
        List<SchemaColumnModel> tableColumnInfoList = graphqlService.selectT(sql, SchemaColumnModel.class);

        // todo has属性
        boolean hasId = false;
        boolean hasCreateTime = false;
        boolean hasUpdateTime = false;
        boolean hasMemo = false;

        for (SchemaColumnModel columnModel :
                tableColumnInfoList) {
            log.debug(JSON.toJSONString(columnModel));
            if ("id".equalsIgnoreCase(columnModel.getColumnName())) {
                hasId = true;
            }
            if ("createTime".equalsIgnoreCase(columnModel.getColumnName())) {
                hasCreateTime = true;
            }
            if ("updateTime".equalsIgnoreCase(columnModel.getColumnName())) {
                hasUpdateTime = true;
            }
            if ("memo".equalsIgnoreCase(columnModel.getColumnName())) {
                hasMemo = true;
            }
            MetaTableColumnEntity metaTableColumn = new MetaTableColumnEntity();
            metaTableColumn.setId(null);
            metaTableColumn.setCreateTime(DateUtil.now());
            metaTableColumn.setUpdateTime(DateUtil.now());
            metaTableColumn.setMetaTableId(importTableId);
            metaTableColumn.setMemo(columnModel.getColumnComment());
            if ("PRI".equalsIgnoreCase(columnModel.getColumnKey())) {
                metaTableColumn.setSourceType("id");
            } else {
                metaTableColumn.setSourceType("extends");
            }

            metaTableColumn.setMetaTableId(importTableId);
            metaTableColumn.setEnName(columnModel.getColumnName());
            metaTableColumn.setChName(columnModel.getColumnComment().split(",")[0].trim());
            metaTableColumn.setSortNo(columnModel.getOrdinalPosition());
            metaTableColumn.setDbType(columnModel.getDataType());
            metaTableColumn.setControlType(this.calColControlType(columnModel));
            metaTableColumn.setRequireFlag(columnModel.getNullableFlag());
            metaTableColumn.setDefaultValue(null);  // 强制不使用默认值
            metaTableColumn.setShowFlag(this.calColShowFlag(columnModel));
            metaTableColumn.setSortFlag(this.calColSortFlag(columnModel));
            metaTableColumn.setAddAble(this.calEditAble(columnModel));
            metaTableColumn.setEditAble(this.calEditAble(columnModel));
            metaTableColumn.setQueryAble(this.calQueryAble(columnModel));
            metaTableColumn.setOptionValue(this.calOptionValue(columnModel));
            metaTableColumn.setWidth(null); // todo Column.setColTableWidth
            metaTableColumn.setSpan(4);     // todo Column.setColParamSpan

            // id 特殊设置
            if ("PRI".equalsIgnoreCase(columnModel.getColumnKey())) {
                metaTableColumn.setAddAble(0);
            }
            this.addMetaTableColumn(metaTableColumn);
        }

        return tableColumnInfoList.size();
    }

    private String calColControlType(SchemaColumnModel columnModel) {
//        控件类型, number:数字; varchar128:短文字; varchar1024:长文字; biz_id:主键; biz_state:状态;
        String dataType = columnModel.getDataType();
        String columnName = columnModel.getColumnName();
        String columnComment = columnModel.getColumnComment();
        SaasAssert.notNull(dataType);
        SaasAssert.notNull(columnName);
        Integer characterLength = columnModel.getCharacterLength();

        String colControlType = "";
        if ("PRI".equalsIgnoreCase(columnModel.getColumnKey())) {
            return "biz_id";
        }
        if ("state".equalsIgnoreCase(columnName)) {
            return "biz_state";
        } else if (columnName.endsWith("_time")) {
            return "datetime";
        } else if (columnName.endsWith("_date")) {
            return "date";
        } else if (columnName.equalsIgnoreCase("enable")) {
            return "biz_flag";
        } else if (columnName.endsWith("_flag")) {
            return "biz_flag";
        } else if (columnName.endsWith("enable")) {
            return "biz_flag";
        } else if (columnComment.indexOf(":") >= 0 && columnComment.indexOf(";") >= 0) {
            return "select";
        }

        switch (dataType) {
            case "tinyint" :
            case "int" :
            case "bigint" :
            case "double" :
            case "decimal" :
                colControlType = "number";
                break;
            case "char" :
            case "varchar" :
                if (characterLength <= 128) {
                    colControlType = "varchar128";
                } else if (characterLength <= 1024) {
                    colControlType = "varchar1024";
                } else {
                    colControlType = "varchar4000";
                }
                break;
            case "datetime" :
            case "timestamp" :
            case "date" :
                colControlType = "datetime";
                break;
            default:
                log.error("colControlType unsupport dataType, " + dataType);
                break;
        }
        return colControlType;
    }

    private Integer calColShowFlag(SchemaColumnModel columnModel) {
        String dataType = columnModel.getDataType();
        String columnName = columnModel.getColumnName();
        SaasAssert.notNull(dataType);
        SaasAssert.notNull(columnName);
        Integer characterLength = columnModel.getCharacterLength();

        if (characterLength != null && characterLength > 128) {
            return 0;
        }
        if (columnName.equalsIgnoreCase("tenant_id")
                || columnName.equalsIgnoreCase("update_time")
                || columnName.equalsIgnoreCase("create_uid")
                || columnName.equalsIgnoreCase("update_uid")
                || columnName.equalsIgnoreCase("memo")) {
            return 0;
        }
        return 1;
    }

    private Integer calColSortFlag(SchemaColumnModel columnModel) {
        String dataType = columnModel.getDataType();
        String columnName = columnModel.getColumnName();
        SaasAssert.notNull(dataType);
        SaasAssert.notNull(columnName);
        Integer characterLength = columnModel.getCharacterLength();

        if (characterLength != null && characterLength > 128) {
            return 0;
        }
        if (columnName.equalsIgnoreCase("update_time")
                || columnName.equalsIgnoreCase("update_uid")
                || columnName.equalsIgnoreCase("memo")) {
            return 0;
        }
        return 1;
    }

    private Integer calEditAble(SchemaColumnModel columnModel) {

        String columnName = columnModel.getColumnName();
        SaasAssert.notNull(columnName);

        if (columnName.equalsIgnoreCase("tenant_id")
                || columnName.equalsIgnoreCase("delete_flag")
                || columnName.equalsIgnoreCase("del_flag")
                || columnName.equalsIgnoreCase("create_time")
                || columnName.equalsIgnoreCase("update_time")
                || columnName.equalsIgnoreCase("create_uid")
                || columnName.equalsIgnoreCase("update_uid")) {
            return 0;
        }
        return 1;
    }

    private Integer calQueryAble(SchemaColumnModel columnModel) {

        String dataType = columnModel.getDataType();
        String columnName = columnModel.getColumnName();
        SaasAssert.notNull(dataType);
        SaasAssert.notNull(columnName);
        Integer characterLength = columnModel.getCharacterLength();

        if (columnName.equalsIgnoreCase("tenant_id")
                || columnName.equalsIgnoreCase("update_time")
                || columnName.equalsIgnoreCase("create_uid")
                || columnName.equalsIgnoreCase("update_uid")
                || columnName.equalsIgnoreCase("memo")
                || columnName.equalsIgnoreCase("del_flag")) {
            return 0;
        } else if (columnName.endsWith("_id")
                || columnName.endsWith("_type")
                || columnName.equalsIgnoreCase("id")) {
            return 1;
        }

        Integer queryAble = 1;
        switch (dataType) {
            case "tinyint" :
                queryAble = 1;
                break;
            case "int" :
            case "bigint" :
            case "double" :
            case "decimal" :
                queryAble = 0;
                break;
            case "char" :
            case "varchar" :
                if (characterLength != null && characterLength <= 55) {
                    queryAble = 1;
                }
                break;
            case "datetime" :
            case "timestamp" :
            case "date" :
                queryAble = 1;
                break;
            default:
                log.error("queryAble unsupport dataType, " + dataType);
                break;
        }

        return queryAble;
    }

    private String calOptionValue(SchemaColumnModel columnModel) {
        String columnName = columnModel.getColumnName();
        SaasAssert.notNull(columnName);
        String columnComment = columnModel.getColumnComment();

        if (columnName.endsWith("_flag")) {
            return "是,否";
        }

        if (StringUtils.isEmpty(columnComment)) {
            return "";
        }
        String[] comments = columnComment.split(",");
        if (comments.length <= 1) {
            return "";
        } else if (comments.length >= 3) {
            log.error("导入表时, columnComment最多包含一个<,> " + columnComment);
            return "";
        }
        String[] options = comments[1].split(";");
        List<String> optionList = new ArrayList<>();
        for (String option :
                options) {
            if (StringUtils.isEmpty(option.trim())) {
                continue;
            }
            String[] items = option.split(":");
            if (items.length == 2) {
                optionList.add(option.trim());
            } else if (items.length > 2) {
                log.error("导入表时, option部分不能包含一个以上<:> " + option);
            }
        }

        if (!optionList.isEmpty()) {
            return String.join(",", optionList);
        } else {
            return "";
        }
    }
}
